#include "AdvPOSIXMsgqueue.hpp"
#include <stdexcept>
#include <errno.h>
#include <fmt/format.h>

AdvPOSIXMsgqueue::AdvPOSIXMsgqueue(const char* queueName)
{
  queueid=mq_open(queueName,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR,nullptr);
  if(queueid==-1)
    throw std::runtime_error(fmt::format("Can't open POSIX MsgQueue: {}",errno));
  mq_attr attr;
  if(mq_getattr(queueid,&attr)==-1)
    throw std::runtime_error(fmt::format("Can't get POSIX MsgQueue attribute: {}",errno));
  receiveBuffer=new char[receiveSize=attr.mq_msgsize];
}

AdvPOSIXMsgqueue::~AdvPOSIXMsgqueue()
{
  delete [] receiveBuffer;
  mq_close(queueid);
}

AdvPOSIXMsgqueue& AdvPOSIXMsgqueue::operator>>(std::string& data)
{
  auto size=Read();
  data=std::string(receiveBuffer,size);
  return *this;
}

AdvPOSIXMsgqueue& AdvPOSIXMsgqueue::operator<<(const std::string& data)
{
  Write(data.data(),data.size());
  return *this;
}

void AdvPOSIXMsgqueue::Write(const char* data,std::size_t size)
{
  if(mq_send(queueid,data,size,0)==-1)
    throw std::runtime_error("Can't send message");
}


std::size_t AdvPOSIXMsgqueue::Read()
{
  ssize_t size=mq_receive(queueid,receiveBuffer,receiveSize,nullptr);
  if(size==-1)
    throw std::runtime_error("Can't send message");
  return size;
}
